package failover

import (
	"context"
	"errors"
	"gitee.com/chicken-c/go-learn/webook/internal/service/sms"
	"sync/atomic"
)

// 基于轮询的实现
type FailoverSMSService struct {
	srvs []sms.Service

	//当先选中下标
	idx uint64
}

func NewFailoverSMSService(srvs []sms.Service) *FailoverSMSService {
	return &FailoverSMSService{
		srvs: srvs,
		idx:  0,
	}
}

// 轮询发送
func (f *FailoverSMSService) Send(ctx context.Context, tqlId string, args map[string]string, number string) error {
	for _, srv := range f.srvs {
		err := srv.Send(ctx, tqlId, args, number)
		if err == nil {
			return err
		}
	}
	return errors.New("发送失败，所有服务商都尝试过了")
}

// rr轮转
func (f *FailoverSMSService) SendV1(ctx context.Context, tqlId string, args map[string]string, number string) error {
	idx := atomic.AddUint64(&f.idx, 1)
	lens := uint64(len(f.srvs))
	for i := idx; i < idx+lens; i++ {
		err := f.srvs[i%lens].Send(ctx, tqlId, args, number)
		if err == nil {
			return nil
		} else if err == context.DeadlineExceeded {
			//超时了
			return err
		}
	}

	return errors.New("发送失败，所有服务商都尝试过了")
}
